﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;

using Ivy.Common.Framework.GeneralUtility;
using Ivy.SiteAdministration.Entity;
using Ivy.SiteAdministration.BusinessLogic;

using Ivy.UserManagement.Entity;
using Ivy.UserManagement.BusinessLogic;

using FrameworkIvy.App_Code;

namespace FrameworkIvy.UserControls
{
    public partial class RegistrationControl : System.Web.UI.UserControl
    {
        #region  Variable & constant
        // All constants and local variable should be declared here
        // TRY NOT TO CREATE PUBLIC VARIABLES INSTEAD USE PROPERTIES FOR THAT PURPOSE.
        // Variable naming convention :- 
        // The naming should be self explanatory, make it long to explain the purpose 
        // and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // Naming convention for all local variable should start with underscore "_"
        // Naming convention for all local constant should start with "_The"
        // Example :    string _CustomerCode = string.Empty;
        // Example :    const string _TheDefaultSmtpServer = "DefaultSmtpServer";
        // ==================== START YOUR CODE FROM NEXT LINE ========================

        //Needed for Authorization logic.
        //For Screens that can be accessed by any users, even guest users, the default Page level IsAnonymousAccess value will be TRUE.
        //But for Screens with access restriction the IsAnonymousAccess value will be FALSE.
        bool IsAnonymousAccess = true;

        //Needed for Authorization logic.
        //For Screens that are Non-Society related (Generic) Activities, the default Page level IsNonOrganizationSpecificActivity value will be TRUE.
        //But for Screens with Activities related to Society the IsNonOrganizationSpecificActivity value will be FALSE.
        bool IsNonOrganizationSpecificActivity = true;

        //Needed for Authorization logic.
        //For Screens with multiple activities, the default ActivityCode value will be [string.Empty], it will be initialized dynamically with query string from the calling event.
        //But for single ActivityCode like only view for reports or only insert etc. we need to assign the specific value below.
        //And for any Screen which only for display by any registered user the ActivityCode value will be [SystemActivities.RetrieveBlogs]
        string _CurrentActivityCode = string.Empty;

        //Needed for Screen initialization logic.
        //For Screens with multiple ScreenActionMode, the default value will be [ScreenActionMode.UnKnown], it will be initialized dynamically with query string from the calling event.
        //but for single ScreenActionMode like only view for reports or only insert etc. we need to assign the specific value below.
        ScreenActionMode _CurrentScreenActionMode = ScreenActionMode.Display;

        string _PersonViewState = "PersonViewState";
        const string _UserViewState = "UserViewState";
        //const string _FeedbackUser = "FeedbackUserViewState";
        const int _TheDefaultVerificationCodeLength = 5;
        #endregion  Variable & constant

        #region Constructor & Destructor
        // Generally not needed in UI layer.
        // Cut and Copy the default constructor for the class inside this region.
        // Generally not required in UI layer.
        // Example:
        // public SampleClassTemplate()
        // {

        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================
        //public SampleAspxUIClassTemplate()
        //{
        //}

        #endregion Constructor & Destructor

        #region Properties
        // Any value/variable that needs to be exposed outside the class we need to create a property.
        // Avoid creating public variables rather create public properties.
        // UI layer may have public custom properties. these are very handy for User Controls.
        // Property naming convention :- Properties will be exposed outside the class, 
        // the naming should be self explanatory, make it long to explain the purpose 
        // and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // All properties should have a corresponding local variable 
        // and the property name and local variable name should match.
        // Example :
        // public string CustomerCode
        // {
        //     get
        //     {
        //         return _CustomerCode;
        //     }
        //     set
        //     {
        //         _CustomerCode = value;
        //     }
        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        #endregion Properties

        #region Events
        // Generally UI layer will have public events.
        // Cut and Copy the default generated events for the class inside this region.
        // ==================== START YOUR CODE FROM NEXT LINE ========================

        protected void Page_Load(object sender, EventArgs e)
        {
            try //All events in pages or user control should have try{} catch {} block.
            {
                if (!Page.IsPostBack)
                {
                    //First check if the current logged in user is having proper role/authorization to access this page or not.
                    if (IsUserAutherization())
                    {
                        //TODO - Your code to display the initial layout/data etc.
                        InitializeScreen();
                    }
                    else
                    {
                        //TODO - Your code to redirect page to "NOT AUTHORIZED" page or any other page as required by the business logic.
                        //Response.Redirect("../BasicPages/UnAuthorizedGuest.aspx");
                        //Response.Redirect("../BasicPages/UnAuthorizedMember.aspx");
                    }
                }
            }
            catch (Exception ex)
            {
                UIExceptionUtility.ExceptionHandler(ex, Server.MapPath("~/"));
            }
        }
        protected void btnCheckAvailablity_Click(object sender, EventArgs e)
        {
            try
            {
                ViewState[_PersonViewState] = null;
                ViewState[_UserViewState] = null;
                if (this.txtLoginId.Value.Trim() == string.Empty)
                {
                    lblAvailibity.ForeColor = System.Drawing.Color.Red;
                    lblAvailibity.Text = "Login id can't be empty";
                }
                else
                {
                    UserManagementBus lUserManagementBus = new UserManagementBus();
                    if (lUserManagementBus.IsLoginIDExisting(this.txtLoginId.Value.Trim()))
                    {
                        lblAvailibity.ForeColor = System.Drawing.Color.Red;
                        lblAvailibity.Text = "Not Available";
                    }
                    else
                    {
                        //Check if login Id is email ID
                        if (!IsInputAnEmail(this.txtLoginId.Value.Trim()))
                        {
                            this.txtPrimaryEmailId.Value = string.Empty;
                            lblAvailibity.ForeColor = System.Drawing.Color.FromArgb(154, 205, 50);
                            lblAvailibity.Text = "Available";
                        }
                        else
                        {
                            Person _Person = lUserManagementBus.GetPersonByPrimaryEmailId(this.txtLoginId.Value.Trim());
                            if (_Person != null)
                            {
                                //Check if this person is already linked in User table or not
                                User _User = lUserManagementBus.GetUserByPersonKey(_Person.PersonKey);
                                if (_User != null)
                                {
                                    lblAvailibity.ForeColor = System.Drawing.Color.Red;
                                    lblAvailibity.Text = "Another signed up person is using this email";

                                }
                                else
                                {
                                    TranslateEntityToUIControlsForPerson(_Person);
                                    //Create a ViewState variable to store this in PERSON obj
                                    CreateViewStateObjectForPerson(_Person);
                                    lblAvailibity.ForeColor = System.Drawing.Color.Green;
                                    lblAvailibity.Text = "Available";
                                }
                            }
                            else
                            {
                                ////check if existing is FeedbackUser table
                                //FeedbackBus lFeedbackBus = new FeedbackBus();
                                //FeedbackUser lFeedbackUser = lFeedbackBus.GetByFeedbackUserEmailId(this.txtLoginId.Text.Trim());
                                //if (lFeedbackUser != null)
                                //{
                                //    TranslateEntityToUIControlsForFeedbackUser(lFeedbackUser);
                                //}
                                //else
                                //{
                                //    //Assign primary email with email login id
                                //    this.txtPrimaryEmailId.Text = this.txtLoginId.Text;
                                //}
                                lblAvailibity.ForeColor = System.Drawing.Color.FromArgb(66, 99, 00);
                                lblAvailibity.Text = "Available";
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //ExceptionUtility.ExceptionHandler(ex, Server.MapPath("~/"));
            }

        }

        protected void btnSignUp_Click(object sender, EventArgs e)
        {
            try
            {
                if (!IsPersonDetailsOnScreenSignUpUser())
                {
                    if ((ViewState[_UserViewState] == null))
                    {
                        User lUser = new User();
                        TranslateUIControlsToEntityForUser(lUser);
                        CreateViewStateObjectForUser(lUser);
                    }
                    UserManagementBus lUserManagementBus = new UserManagementBus();
                    Person _Person = (Person) ViewState[_PersonViewState];
                    User _User = (User) ViewState[_UserViewState];
                    if (lUserManagementBus.SignUp(_Person, _User))
                    {
                       //Send email for primary email verification.
                       lUserManagementBus.SendEmalVerificationCodeByEmailForPrimaryEmail(_Person, _User);
                       lUserManagementBus.SendNewSignUpNotificationEmail(_Person, _User);

                       ViewState[_PersonViewState] = null;
                       ViewState[_UserViewState] = null;
                       this.SignUpModalPopupExtender.Show();
                    }
                    
                }
                
            }

            catch (Exception ex)
            {

            }
        }

        protected void btnGetStartlogin_Click(object sender, EventArgs e)
        {
            this.SignUpModalPopupExtender.Hide();
            Response.Redirect("~/LoginProcess/Login.aspx");
        }
        #endregion Events

        #region Public Methods
        // UI layer may have public custom Methods. These are very handy for User Controls.
        // Any method that needs to be exposed outside the class will be created inside this region.
        // Public Method naming convention :- Public Method will be exposed outside the class, 
        // The input and output parameters are also going to be exposed outside the class
        // the naming should be self explanatory, make it long to explain the purpose 
        // and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // Example :
        // public bool RegisterNewCustomer(Customer Customer)
        // {
        //     bool IsCustomerDataSaved = false;
        //     //TO DO logic to save data
        //     IsCustomerDataSaved = InsertCustomerDataUsingDao(Customer);
        //     return IsCustomerDataSaved;
        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        #endregion Public Methods

        #region Private Methods
        // All local class level methods will be inside this region. Mostly these are helper methods.
        // Private Method naming convention :- The naming should be self explanatory, 
        // make it long to explain the purpose and use PascalCase to seperate words as shown in the example below.
        // DO NOT USE ANY ABBRIVIATION use full word (like "Customer" instead of "Cust"
        // Input parameter will have a "p" as prefix. 
        // This will help the parameter variable that the value is originated outside this private method.
        // Example :
        // public bool InsertCustomerDataUsingDao(Customer pCustomer)
        // {
        //     bool IsCustomerDataInsertedSuccessfully = false;
        //     //TO DO logic to save data
        //     //....
        //     //....
        //     return IsCustomerDataInsertedSuccessfully;
        // }
        // ==================== START YOUR CODE FROM NEXT LINE ========================


        /// <summary>
        /// This method is to check if the current logged in user is having proper role/authorization to access this page or not.
        /// </summary>
        private bool IsUserAutherization()
        {
            bool _IsUserAutherization = false;
            //TODO - Your code to check authorization goes here.


            //Check if the Screen has Access Restriction.
            if (IsAnonymousAccess)
            {
                _IsUserAutherization = true; //by default the activity can be executed by any person even guest user.
            }
            else
            {
                User _User = SessionUtility.GetCurrentLoginUser();
                if (_User != null)
                {
                    ////Check if the Screen Activity is a Non-Society activity then the  _UserDefaultOrzanization code will be -1 (SYSTEM)
                    Sys_OrganizationMaster _UserDefaultOrzanization;
                    _UserDefaultOrzanization = SessionUtility.GetCurrentLoginUserOrzanization();
                    UserManagementBus _UserManagementBus = new UserManagementBus();

                    //if (IsNonOrganizationSpecificActivity)
                    //{
                    //    SiteAdministrationBus _SiteAdministrationBus = new SiteAdministrationBus();
                    //    //Set _UserDefaultOrzanization = System/-1
                    //    _UserDefaultOrzanization = _SiteAdministrationBus.GetSys_OrganizationMasterByKey(-1);
                    //}

                    if (_UserDefaultOrzanization != null)
                    {
                        //Check if QueryString for ActivityCode is supplied, then this Screen is for multiple Activities 
                        //and the current instance ActivityCode is supplied by the QueryString. 
                        //In that case we need to overwrite the default ActivityCode from string.Empty to the QueryString value.
                        if (!string.IsNullOrEmpty(Request.QueryString["ActivityCode"]))
                        {
                            _CurrentActivityCode = Request.QueryString["ActivityCode"].ToString();
                        }
                        //Get the Authorization details for the current logged in user and the the role
                        _IsUserAutherization = _UserManagementBus.IsAcitivityAuthorized(_UserDefaultOrzanization.OrganizationCode, _CurrentActivityCode, _User.UserLoginId);
                    }
                }
            }
            return _IsUserAutherization;
        }

        /// <summary>
        /// This method is to clear all UI controls which are data binded.
        /// </summary>
        private void ClearScreen()
        {
        }

        /// <summary>
        /// This method is to bind all the UI control like dropdown list or list box etc with the required initial data, 
        /// </summary>
        private void FillLoadLookUpData()
        {
        }

        /// <summary>
        /// This method is applicable only for Screens with multiple ScreenActionMode, where QuerySting is Involved
        /// </summary>
        private void InitializeScreen()
        {
            //Check if QueryString for ScreenActionMode is supplied, then this Screen is with multiple ScreenActionMode 
            //and the current instance ScreenActionMode is supplied by the QueryString. 
            //In that case we need to overwrite the default ScreenActionMode from ScreenActionMode.UnKnown to the QueryString value.
            if (!string.IsNullOrEmpty(Request.QueryString["ScreenMode"]))
            {
                _CurrentScreenActionMode = (ScreenActionMode)Enum.Parse(typeof(ScreenActionMode), Request.QueryString["ScreenMode"].ToString());
                //Check if the Screen is a single ScreenActionMode 
                if (_CurrentScreenActionMode != ScreenActionMode.UnKnown)
                {
                    //TODO: Logic to Set the screen controls to respective action mode. Example :-
                    //In case of [New] mode the screen should be clear of all existing data.
                    //In case of [Edit] mode the screen should be filled with the existing record that is to be edited.
                    if (_CurrentScreenActionMode == ScreenActionMode.New)
                    {
                        //Check for any other QueryString as per business logic. Example:-
                        //if (!string.IsNullOrEmpty(Request.QueryString["SocietyKey"]))
                        //{
                        //TODO: business logic.
                        //}
                    }
                    if (_CurrentScreenActionMode == ScreenActionMode.Edit)
                    {
                        //Check for any other QueryString as per business logic. Example:-
                        //if (!string.IsNullOrEmpty(Request.QueryString["SocietyKey"]))
                        //{
                        //TODO: business logic.
                        //}
                    }
                    if (_CurrentScreenActionMode == ScreenActionMode.Display)
                    {
                        //Check for any other QueryString as per business logic. Example:-
                        //if (!string.IsNullOrEmpty(Request.QueryString["SocietyKey"]))
                        //{
                        //TODO: business logic.
                        //}
                    }
                }
            }
            else
            {
                if (_CurrentScreenActionMode != ScreenActionMode.Display)
                {
                    //Check for any other QueryString as per business logic. Example:-
                    //if (!string.IsNullOrEmpty(Request.QueryString["SocietyKey"]))
                    //{
                    //TODO: business logic.
                    //}
                }
            }

            ClearScreen();
            FillLoadLookUpData();
            //TODO: rest of the display logic code
        }

        /// <summary>
        /// This method is to copy the entity properties that need to be displayed in the UI controls to the UI control.
        /// Example - [pUser] is an instance of an entity and is filled with specific USER data.
        /// and this user instance is to be displayed is an UI control text boxes.
        /// A sample code will look like the following:
        ///  this.txtFirstName.Text = pUser.UserFirstName; 
        ///  this.txtLastName.Text  = pUser.UserLastName; 
        ///  this.txtLoginId.Text   = pUser.UserLoginID;
        /// </summary>
        private void TranslateEntityToUIControls()
        {
        }

        /// <summary>
        /// This method is to copy the user entered data from the UI controls to the entity instance that will be used to sent the entity to any other layer.
        /// Example - [pUser] is an instance of an entity and is to be filled with specific USER data that has been captured in the screen.
        /// A sample code will look like the following:
        ///  pUser.UserFirstName = this.txtFirstName.Text; 
        ///  pUser.UserLastName  = this.txtLastName.Text; 
        ///  pUser.UserLoginID   = this.txtLoginId.Text; 
        /// </summary>
        private void TranslateUIControlsToEntity()
        {
        }

        private void TranslateUIControlsToEntityForPerson(Person pPerson)
        {

            pPerson.PersonFirstName = this.txtFirstName.Value;
            pPerson.PersonLastName = this.txtLastName.Value;
            pPerson.PersonPrimaryEmailID = this.txtPrimaryEmailId.Value;
            pPerson.PersonPrimaryEmailVerificationCode = StringUtility.GenerateRandomString(5);
            pPerson.PersonPrimaryMobileNumber = this.txtMobileNo.Value.Trim();
            if (pPerson.PersonPrimaryMobileNumber == string.Empty)
            {
                pPerson.PersonPrimaryMobileVerificationCode = StringUtility.GenerateRandomString(_TheDefaultVerificationCodeLength);
            }
            if (this.txtDateOfBirth.Text.ToString() == string.Empty)
            {
                pPerson.PersonDateOfBirth = null;
            }
            else
            {
                // 22/1/2016 Changed Date format By Ram pravesh k.r
                pPerson.PersonDateOfBirth = DateTimeUtility.ConvertStringToDateTime(this.txtDateOfBirth.Text, InputDateTimeFormat.DD_MM_YYYY);
            }
            pPerson.Sys_CreatedByID = "1";
            pPerson.Sys_OrganizationID = -1;

        }

        private void TranslateUIControlsToEntityForUser(User pUser)
        {
            //pUser.UserPersonKey = pUser.UserPersonKey;
            pUser.UserLoginId = this.txtLoginId.Value.Trim();
            pUser.UserPassword = this.txtPassword.Value.Trim();
            if (IsInputAnEmail(this.txtLoginId.Value.Trim()))
            {
                pUser.UserLoginIdType = 2;
            }
            else
            {
                //Need to check if other type of login Id like fcebook id or google Id. Currently hard coding with just email and simle login Id
                pUser.UserLoginIdType = 1;
            }
            pUser.Sys_CreatedByID = pUser.UserPersonKey.ToString();
        }


        private bool IsInputAnEmail(string pInputText)
        {            
            bool IsEmailId = false;
            string strRegex = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}" + "\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\" + ".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
            Regex re = new Regex(strRegex);
            if (re.IsMatch(pInputText))
            {
                IsEmailId = true;
            }
            return IsEmailId;
        }

        private void CreateViewStateObjectForPerson(Person pPerson)
        {
            ViewState[_PersonViewState] = pPerson;
        }

        private void CreateViewStateObjectForUser(User pUser)
        {
            ViewState[_UserViewState] = pUser;
        }

        private void TranslateEntityToUIControlsForPerson(Person pPerson)
        {
            this.txtFirstName.Value = pPerson.PersonFirstName;
            this.txtLastName.Value = pPerson.PersonLastName;
            this.txtPrimaryEmailId.Value = pPerson.PersonPrimaryEmailID;
            this.txtMobileNo.Value = pPerson.PersonPrimaryMobileNumber;
            if (pPerson.PersonDateOfBirth != null)
            {
                this.txtDateOfBirth.Text = pPerson.PersonDateOfBirth.Value.ToShortDateString();
            }
        }

        //private void TranslateEntityToUIControlsForFeedbackUser(FeedbackUser pFeedbackUser)
        //{
        //    this.txtFirstName.Value = pFeedbackUser.FeedbackUserName;
        //    this.txtPrimaryEmailId.Value = pFeedbackUser.FeedbackUserEmail;
        //}

        private bool IsPersonDetailsOnScreenSignUpUser()
        {

            bool IsSignedUp = false; //Assuming by default the person is not signed up
            UserManagementBus lUserManagementBus = new UserManagementBus();
            Person lPerson;
            if (ViewState[_PersonViewState] == null)
            {
                //Check if login ID available or not
                if (lUserManagementBus.IsLoginIDExisting(this.txtLoginId.Value.Trim()))
                {
                    IsSignedUp = true;
                    lblAvailibity.ForeColor = System.Drawing.Color.Red;
                    lblAvailibity.Text = "Not Available";
                }
                else
                {
                    if (IsInputAnEmail(this.txtLoginId.Value.Trim()))
                    {
                        if (this.txtLoginId.Value.Trim() != this.txtPrimaryEmailId.Value.Trim())
                        {
                            IsSignedUp = true;
                            lblAvailibity.ForeColor = System.Drawing.Color.Red;
                            lblAvailibity.Text = "As your Login Id is an email, it should match with your primary email";
                        }
                        else
                        {
                            //Validate if PrimaryEmail is unique in PERSON primary Email ID
                            lPerson = lUserManagementBus.GetPersonByPrimaryEmailId(this.txtPrimaryEmailId.Value);

                            if (lPerson != null)
                            {
                                //Check if this person is already linked in User table with some other login ID
                                User _User = lUserManagementBus.GetUserByPersonKey(lPerson.PersonKey);
                                if (_User != null)
                                {
                                    IsSignedUp = true;
                                    lblAvailibity.ForeColor = System.Drawing.Color.Red;
                                    lblAvailibity.Text = "Another signed up person is using this email";
                                }
                                else
                                {
                                    IsSignedUp = false;
                                    //Create a ViewState variable to store this in PERSON obj
                                    CreateViewStateObjectForPerson(lPerson);
                                    lblAvailibity.ForeColor = System.Drawing.Color.Green;
                                    lblAvailibity.Text = "Available";
                                }
                            }
                            else
                            {
                                IsSignedUp = false;
                                lPerson = new Person();
                                TranslateUIControlsToEntityForPerson(lPerson);
                                CreateViewStateObjectForPerson(lPerson);
                                lblAvailibity.ForeColor = System.Drawing.Color.Green;
                                lblAvailibity.Text = "Available";
                            }
                        }
                    }
                    else
                    {
                        IsSignedUp = false;
                        lPerson = new Person();
                        TranslateUIControlsToEntityForPerson(lPerson);
                        CreateViewStateObjectForPerson(lPerson);
                        lblAvailibity.ForeColor = System.Drawing.Color.Green;
                        lblAvailibity.Text = "Available";
                    }
                }
            }
            return IsSignedUp;
        }

        public string ReplaceKeyWords(Match m)
        {
            return ("<span class=highlight>" + m.Value + "</span>");
        }

        #endregion Private Methods
    }
}